﻿#encoding: utf-8
#this file can be used in other ruby file by loading 'wechat_api.rb'

require 'rest-client'   #to use RestClient
require 'json'          #to use JSON
require 'awesome_print' #to use ap helper

def get_wechat_access_token force=false
  if @rds.nil?
    load 'rds_api.rb'
    @rds = @rds_tt
  end
  return get_foodtrust_wechat_access_token if @rds == @rds_fc
  #return get_totem_wechat_access_token force
  return get_wechat_stable_access_token
end

def get_weapp_access_token force=false
  uri = "https://mall.totembio.cn/api/gat?app=weapp&code=#{ENV['PSI_PASSWORD']}#{force ? '&force=true' : ''}"
  res = RestClient.get uri
  return JSON.parse(res.body)['data']['token']
end

def get_wechat_stable_access_token(platform='public')
    appid = platform == 'weapp' ? ENV['WX_APP_ID'] :
        platform == 'public' ? ENV['MP_APP_ID'] : nil
    secret = platform == 'weapp' ? ENV['WX_APP_SECRET'] :
        platform == 'public' ? ENV['MP_APP_SECRET'] : nil

    if appid.nil? || secret.nil?
        raise 'Invalid platform or environment variables not set'
    end

    response = RestClient.post 'https://api.weixin.qq.com/cgi-bin/stable_token', {
        grant_type: 'client_credential',
        appid: appid,
        secret: secret
    }.to_json, content_type: :json, accept: :json

    access_token = JSON.parse(response.body)['access_token']
    #ap JSON.parse(response.body)
    return access_token
end

def get_wework_access_token force=false
  uri = "https://mall.totembio.cn/api/gat?app=wework&code=#{ENV['PSI_PASSWORD']}#{force ? '&force=true' : ''}"
  res = RestClient.get uri
  return JSON.parse(res.body)['data']['token']
end

def wework_access_token
   @kat = get_wework_access_token if @kat.nil?
   return @kat
end

#return hash instead of JSON string
def get_foodtrust_wechat_access_token
   res = RestClient.get "https://foodtrust.cn/wx/get-access-token?badge=#{ENV['RDS_AGENT']}"
   #ap res.code;  res.cookies; ap res.headers; ap res.body
   return JSON.parse(res.body)['access_token']
end

def get_totem_wechat_access_token force=false
  uri = "https://mall.totembio.cn/api/gat?app=wechat&code=#{ENV['PSI_PASSWORD']}#{force ? '&force=true' : ''}"
  res = RestClient.get uri
  return JSON.parse(res.body)['data']['token']
end

def wechat_access_token
   @wat = get_wechat_access_token if @wat.nil?
   return @wat
end

def weapp_access_token
  @mat = get_weapp_access_token if @mat.nil?
  return @mat
end

#data should be hash, not JSON string
def wechat_post api_name, data

  api = api_name.to_s
  base = 'https://api.weixin.qq.com/'
  base = 'https://qyapi.weixin.qq.com/' if api.include? 'Wework'
  wat = wechat_access_token
  wat = weapp_access_token if api.include? 'Weapp'
  wat = wework_access_token if api.include? 'Wework'

  apiURLs={
    :sendTemplateMessage => "cgi-bin/message/template/send?access_token=#{wat}",
    :sendTextMessage => "cgi-bin/message/custom/send?access_token=#{wat}",
    :batchGet => "cgi-bin/user/info/batchget?access_token=#{wat}",
    :generateWeappUrlLink => "wxa/generate_urllink?access_token=#{wat}",
    :batchGetWeworkContactList => "cgi-bin/externalcontact/batch/get_by_user?access_token=#{wat}",
    :getWeworkCorpTagList => "cgi-bin/externalcontact/get_corp_tag_list?access_token=#{wat}",
    :getWeworkStrategyTagList => "cgi-bin/externalcontact/get_strategy_tag_list?access_token=#{wat}",
    :getWeworkGroupChatList => "cgi-bin/externalcontact/groupchat/list?access_token=#{wat}",
    :getWeworkGroupChatDetails =>"cgi-bin/externalcontact/groupchat/get?access_token=#{wat}",
    :remarkWeworkExternalContact =>"cgi-bin/externalcontact/remark?access_token=#{wat}",
    :markWeworkTag => "cgi-bin/externalcontact/mark_tag?access_token=#{wat}",
    :sendWeworkNotice => "cgi-bin/message/send?access_token=#{wat}",
    :convertWeworkOpenidToUserid => "cgi-bin/user/convert_to_userid?access_token=#{wat}"
  }
  url = base + apiURLs[api_name]

  res = RestClient.post url, data.to_json
  return JSON.parse res.body
end

def wechat_get api_name, data

  api = api_name.to_s
  base = 'https://api.weixin.qq.com/'
  base = 'https://qyapi.weixin.qq.com/' if api.include? 'Wework'
  wat = wechat_access_token
  wat = weapp_access_token if api.include? 'Weapp'
  wat = wework_access_token if api.include? 'Wework'

  apiURLs={
    :getUserInfo => "cgi-bin/user/info?access_token=#{wat}",
    :getOpenidList => "cgi-bin/user/get?access_token=#{wat}",
    :getWeworkContactPoints => "cgi-bin/externalcontact/get_follow_user_list?access_token=#{wat}",
    :getWeworkContactDetails => "cgi-bin/externalcontact/get?access_token=#{wat}",
    :getAllPrivateTemplate => "cgi-bin/template/get_all_private_template?access_token=#{wat}"
  }

  args = ""
  data.each do |key, value|
    args += "&#{key}=#{value}"
  end
  url = base + apiURLs[api_name] + args

  res = RestClient.get url
  return JSON.parse res.body
end

def send_bot_message content, list
    #content =   "今日丰巢实时新增用户反馈<font color=\"warning\">132例</font>，请相关同事注意。\n >类型:<font color=\"comment\">用户反馈</font> \n >普通用户反馈:<font color=\"comment\">117例</font> \n >VIP用户反馈:<font color=\"comment\">15例</font>" 
    data = {
        "msgtype": "markdown",
        "markdown": {
            "content": content,
            "mentioned_list": list
        }
    }

    res = RestClient.post ENV['WWBOT_WC'], data.to_json
    return JSON.parse res.body
end

#botcode 'WWBOT_WC' 'WWBOT_XT'
def send_message_to_bot botcode, content, list
    data = {
        "msgtype": "markdown",
        "markdown": {
            "content": content,
            "mentioned_list": list
        }
    }
    bot_url = ENV[botcode] 
    bot_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=8e1b476e-1de3-4a14-9c0c-fa2738ff4587' if ENV[botcode].nil?
    res = RestClient.post bot_url, data.to_json
    return JSON.parse res.body
end

def send_text_to_bot botcode, content, list=['@all'], mobile_list=[]
    data = {
        "msgtype": "text",
        "text": {
            "content": content,
            "mentioned_list": list,
            "mentioned_mobile_list": mobile_list
        }
    }
    bot_url = ENV[botcode]
    bot_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=8e1b476e-1de3-4a14-9c0c-fa2738ff4587' if ENV[botcode].nil?
    res = RestClient.post bot_url, data.to_json
    return JSON.parse res.body
end

def send_balance_notice openids
    notice = {
        touser: 'owHN1t0ETyOD1p_J324Gcb9twHuk',
        template_id:  'JJq04n18SSmcNItaCwcLDmNqFJoGCIk5nvOWPm3KvJg',
        url:  'https://shop.foodtrust.cn/m/accountv4',  
        data:  {
            first:  { value:  "您的账户余额有变动，详情如下", color:  '#173177' },
            keyword1:  { value:   "会员账户余额", color:  '#173177' },
            keyword2:  { value:  '系统每日批处理', color:  '#ff0000' },
            keyword3:  { value:  "团购订单或特定区域运费返回\n运费退回规则：\n *所有已提交的团购订单（无论是否拼成）\n *特定小区大于88元的日常订单\n *广东省外快递改为到付(满298另有积分奖励)", color:  '#173177' },
            keyword4:  { value:  '+10.00', color:  '#0000ff' },
            keyword5:  { value:  '点击详情查看最新余额', color:  '#0000ff' },
            remark:  { value: "FOODTRUST® 丰巢有机\n让健康和友善触手可及", color:  '#88b04b' },
        }
    }
    openids.each do |openid|
        notice.store(:touser,openid) #注意，如果是'touser' 就不工作了
        res = wechat_post :sendTemplateMessage, notice
        ccNotice notice
    end
end

#发送微信公众号模板消息的简化版本
def send_mp_ts touser, template_id, url, miniprogram, data

    notice = { touser: touser, template_id:  template_id, url:  url, miniprogram: miniprogram, data: data }
    res = wechat_post :sendTemplateMessage, notice
    return res

end

def totem_points_change_notice ( openid='oqlyX6deLDP2EWlk0qZgWCU7wH6I', operation="账户获赠会员积分", bonus=0,
        url='https://mta.totembio.cn/', miniprogram={ appid: "wx1b441d1a37b278e1", pagepath:  "pages/user_integral/index" },
        message='0.0元(活动免费赠送)', remark = '更多积分获得途径，请联系服务专员获得协助'
    )
    touser = openid
    #template_id = 'WhhmEpB9VXlMRkLUbsTWTqxHb44FbZIb3QCA_fV3m44'
    #template_id = 'KWPogM5R5gukvXTOShsqXyQCAH7LB5JKyVpJYkfqqPY'
    template_id = 'NFnG6uAdy9LP-t419odIUq05j3Y8H69UN-GTK_akQ9Y'
    data = {
        first:  '',
        keyword1: { value: '图腾生命医学小程序' },
        keyword2:  { value:   "#{message}"},
        keyword3:  { value:   "#{operation}"},
        keyword4:  { value:  "#{bonus.to_f.round(2)}分"},
        keyword5:  { value:  "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"},
        remark:  ''
    }
    res =  send_mp_ts touser, template_id, url, miniprogram, data
    ap res
    return true if res['errcode'] == 0
    return false
end

def send_specific_points_notice openid, points, reason, url, content, newPoints
    notice = {
        touser: 'owHN1t0ETyOD1p_J324Gcb9twHuk',
        template_id:  'RTPLTnnAvu-jI7fsAoWu0CwLpGZwoMBXK3bRlIxrkU8',
        url:  'https://shop.foodtrust.cn/m/accountv4',  
        data:  {
            first:  { value:  "您的会员积分有变动，详情如下", color:  '#173177' },
            keyword1:  { value:   "#{Time.now}", color:  '#173177' },
            keyword2:  { value:  '200分', color:  '#ff0000' },
            keyword3:  { value:  "见证诚信，传播友善，记录真实。\n积分规则：\n参与平台每篇文章讨论最多可获一次积分\n *单项正常留言50分\n *全平台首次留言200积分\n *关联购买顾客留言200分\n *按最高分值项计算", color:  '#173177' },
            keyword4:  { value:  newPoints, color:  '#0000ff' },
            remark:  { value: "点击详情获得更多分享\nFOODTRUST® 让健康和友善触手可及", color:  '#88b04b' },
        }
    }

    notice.store(:touser,openid) #注意，如果是'touser' 就不工作了
    notice.store(:url,url)
    notice[:data].store(:first, {value: content, color: '#173177'})
    notice[:data].store(:keyword2, {value: points, color: '#ff0000'})
    notice[:data].store(:keyword3, {value: reason, color: '#173177'})
    res = wechat_post :sendTemplateMessage, notice

    ccNotice notice

    return res
end

def ccNotice notice
  return
  notice.store(:touser,'owHN1tzPJOSQ2qlnbRCSo-Ke6G9k') #CC to 丰巢小蜜
  wechat_post :sendTemplateMessage, notice
  notice.store(:touser,'owHN1t0ETyOD1p_J324Gcb9twHuk') #CC to 董学锋
  wechat_post :sendTemplateMessage, notice
  notice.store(:touser,'owHN1t3GUvWYmKsxbwZdSpQDo4O4') #CC to 庞建全
  wechat_post :sendTemplateMessage, notice
end

def send_text_message openid, content
    notice = {
        touser: 'owHN1t0ETyOD1p_J324Gcb9twHuk',
        msgtype: 'text',
        text: {
            content: 'Hello,World'
        }
    }
    notice.store(:touser,openid) #注意，如果是'touser' 就不工作了
    notice[:text].store(:content,content)
    res = wechat_api :sendTextMessage, wechat_access_token, notice
    return res
end

def send_specific_balance_notice openid, balance, reason, url, content
    notice = {
        touser: 'owHN1t0ETyOD1p_J324Gcb9twHuk',
        template_id:  'JJq04n18SSmcNItaCwcLDmNqFJoGCIk5nvOWPm3KvJg',
        url:  'https://shop.foodtrust.cn/m/accountv4',  
        data:  {
            first:  { value:  "您的账户余额有变动，详情如下", color:  '#173177' },
            keyword1:  { value:   "会员账户余额", color:  '#173177' },
            keyword2:  { value:  '系统每日批处理', color:  '#ff0000' },
            keyword3:  { value:  "团购订单或特定区域运费返回\n运费退回规则：\n *所有已提交的团购订单（无论是否拼成）\n *特定小区大于88元的日常订单\n *广东省外快递改为到付(满298另有积分奖励)", color:  '#173177' },
            keyword4:  { value:  '+10.00', color:  '#0000ff' },
            keyword5:  { value:  '点击详情查看会员对账单及最新余额', color:  '#0000ff' },
            remark:  { value: "关注微信公号foodtrust联系客服\nFOODTRUST® 丰巢有机\n让健康和友善触手可及", color:  '#88b04b' },
        }
    }

    notice.store(:touser,openid) #注意，如果是'touser' 就不工作了
    notice.store(:url,url)
    notice[:data].store(:first, {value: content, color: '#173177'})
    notice[:data].store(:keyword3, {value: reason, color: '#173177'})
    notice[:data].store(:keyword4, {value: balance, color: '#0000ff'})
    res = wechat_post :sendTemplateMessage, notice

    ccNotice notice
    return res

end

def send_confirm_notice openid, info, order_number, order_type, remark, url, flag
    notice = {
        touser: 'owHN1t0ETyOD1p_J324Gcb9twHuk',
        template_id:  'mYo2eI-KIN9FwW3vQSG3L34valYzs87eZx97mEfQvsA',
        url:  'https://foodtrust.cn/first-order-qna/',
        data:  {
            first:  { value:  "【客户名】您好，订单已收到，我们将按团购商品说明为您如期安排配送或产地直发。", color:  '#173177' },
            keyword1:  { value:   "订单号", color:  '#173177' },
            keyword2:  { value:  '配送类型', color:  '#ff0000' },
            remark:  { value: "任何问题请联系丰巢小蜜18998382701，微信同号。\nFOODTRUST® 丰巢有机\n让健康和友善触手可及", color:  '#88b04b' },
        }
    }

    notice.store(:touser,openid) #注意，如果是'touser' 就不工作了
    if flag == 1
        notice.store(:url,'https://foodtrust.cn/first-order-qna/')
    else
        notice.store(:url,url)
    end

    notice[:data].store(:first, {value: info, color: '#173177'})
    notice[:data].store(:keyword1, {value: order_number, color: '#173177'})
    notice[:data].store(:keyword2, {value: order_type, color: '#ff0000'})
    notice[:data].store(:remark, {value: remark, color: '#88b04b'})

    res = wechat_post :sendTemplateMessage, notice
    ccNotice notice if flag == 1 # only send 1st order to foodcherry, usually use order[:order_times]

    return res
end

def get_mp_user_info openid

  data = { openid: openid, lang: 'zh-CN' }
  wechat_get :getUserInfo, data

end

def get_mp_openids

  total = 0
  next_openid = ''
  openid_list = []

  begin

    data = { next_openid: next_openid}
    res = wechat_get :getOpenidList, data
    total = res['total']
    count = res['count']
    odata = res['data']
    next_openid = res['next_openid']
    openids = odata['openid']
    openid_list += openids

  end while count != total

  return openid_list

end

def get_mp_user_info_list openids = []

  openids = get_mp_openids if openids.size == 0
  openids_group = []

  #接口支持查询列表不超过100个元素
  start_idx = 0
  begin
    end_idx = start_idx + 99
    this_group = openids[start_idx..end_idx]
    openids_group += [this_group]
    start_idx = end_idx + 1
  end while start_idx < openids.size

  user_info_list = []

  openids_group.each do |group|

    users = []
    index = 1
    group.each do |openid|
      user = {}
      user.store 'openid', openid
      user.store 'lang', 'zh_CN'
      users += [user]
      break if index == 100
      index += 1
    end
    data = {}
    data.store 'user_list', users
    res = wechat_post :batchGet, data #这个鸟接口每次只能最多100个数据
    user_info_list += res['user_info_list']

  end

  return user_info_list

end

def get_wework_corp_tag_list

  data = { tag_id: [], group_id: [] }
  res = wechat_post :getWeworkCorpTagList, data       #暂时不分页了，反正不多
  tagList = {}
  res['tag_group'].each do |r|
    r['tag'].each do |t|
      tagList.store t['name'], t['id']
    end
  end
  return tagList

end

def get_all_private_template
  data = {}
  res = wechat_get :getAllPrivateTemplate, data
  return res
end

def get_wework_corp_tag_name_list

  data = { tag_id: [], group_id: [] }
  res = wechat_post :getWeworkCorpTagList, data       #暂时不分页了，反正不多
  tagList = {}
  res['tag_group'].each do |r|
    r['tag'].each do |t|
      tagList.store t['id'], t['name']
    end
  end
  return tagList

end

def get_wework_strategy_tag_list

  data = { strategy_id: 1, tag_id: [], group_id: [] }
  res = wechat_post :getWeworkStrategyTagList, data       #暂时不分页了，反正不多
  ap res

end

def get_wework_group_chat_list

  data = { status_filter: 0, owner_filter: {}, cursor: '', limit: 1000 }
  res = wechat_post :getWeworkGroupChatList, data       #暂时不分页了，反正不多
  chat_id_list = []
  res['group_chat_list'].each do |g|
    chat_id_list += [g['chat_id']]
  end
  return chat_id_list

end

def remark_wework_external_contact userid, external_userid, remark, description
    #{ "userid":"zhangsan", "external_userid":"woAJ2GCAAAd1asdasdjO4wKmE8Aabj9AAA", "remark":"备注信息", "description":"描述信息", "remark_company":"腾讯科技", "remark_mobiles":[ "13800000001", "13800000002" ], "remark_pic_mediaid":"MEDIAID" }
    return if userid == '' || external_userid == ''
    data =  { userid: userid, external_userid: external_userid, remark: remark, description: description}
    data =  { userid: userid, external_userid: external_userid, description: description} #暂时不更新备注
    res = wechat_post :remarkWeworkExternalContact, data
    #ap res
end

def mark_wework_tag userid, external_userid, add_tags, remove_tags
    # { "userid":"zhangsan", "external_userid":"woAJ2GCAAAd1NPGHKSD4wKmE8Aabj9AAA", "add_tag":["TAGID1","TAGID2"], "remove_tag":["TAGID3","TAGID4"] }  
    return if userid == '' || external_userid == ''
    data = {userid: userid, external_userid: external_userid, add_tag: add_tags, remove_tag: remove_tags }
    res = wechat_post :markWeworkTag, data
    #ap res
end

def get_wework_group_chat_members chat_id
  data = { chat_id: chat_id, need_name: 1}
  res = wechat_post :getWeworkGroupChatDetails, data
  member_list = res['group_chat']['member_list']
  members = []
  member_list.each do |m|
    members += [m]
  end
  return members
end

def get_wework_external_list userid_list = []

  userid_list = get_wework_contact_points if userid_list.size == 0
  userid_list_group = []

  #接口支持查询列表不超过100个元素
  start_idx = 0
  begin
    end_idx = start_idx + 99
    this_group = userid_list[start_idx..end_idx]
    userid_list_group += [this_group]
    start_idx = end_idx + 1
  end while start_idx < userid_list.size

  external_contact_list = []

  userid_list_group.each do |userids|
    next_cursor = ''
    begin
      data = { userid_list: userids, cursor: next_cursor, limit: 100}
      res = wechat_post :batchGetWeworkContactList, data
      contacts = res['external_contact_list']
      #last_contact = contacts[(contacts.size-1)]
      #ap last_contact
      next_cursor = res['next_cursor']
      external_contact_list += contacts
    end while next_cursor != ''
  end

  return external_contact_list

end

def get_wework_external_contact_details userid

    external_contact = {}
    follow_users = []
    next_cursor = ''
    begin
      data = { external_userid: userid, cursor: next_cursor}
      res = wechat_get :getWeworkContactDetails, data
      external_contact = res['external_contact']
      follow_user = res['follow_user']
      follow_users += follow_user
      next_cursor = res['next_cursor'].to_s
    end while next_cursor != ''
    details = {}
    details.store 'external_contact', external_contact
    details.store 'follow_users', follow_users
    return details
end

=begin

  https://wxaurl.cn/VO2ZpEfEBPa 
  #小程序个人中心
  data = { path: "/pages/user/user", query: "", is_expire:false }

  https://wxaurl.cn/dm1jGb1ZF6l
  #积分详情
  data = { path: "/pages/user_integral/index", query: "", is_expire:false }

  https://wxaurl.cn/p7I02poUXQi
  #查看订单详情
  data = { path: "/pages/order_details/index", query: "order_id=wx163721572344951700", is_expire:true, expire_type:1, expire_interval:179 }

  #https://wxaurl.cn/JP1VqTLQSIg
  #放假通知
  data = { path: "/pages/news_details/index", query: "id=113&spreader_uid=736", is_expire:true, expire_type:1, expire_interval:179 }

  #带spreader的放假通知
  #https://wxaurl.cn/K911199ja7h
  data = { path: "/pages/news_details/index", query: "id=113&spreader_uid=736", is_expire:true, expire_type:1, expire_interval:179 }

  #订单处理后联系客户时发送的小图链接微信
  #https://wxaurl.cn/O0b6sv5dsJm
  data = { path: "/pages/news_details/index", query: "id=90&spreader_uid=736", is_expire:false }

  #关注微信公众号的小程序链接
  https://wxaurl.cn/XHSCyiLFB1d
  data = { path: "/pages/news_details/index", query: "id=182&spreader_uid=736", is_expire:false }
  ap gen_weapp_url_link data

  #订单发货或异常短信中带的小程序关注公众号页面链接
  https://wxaurl.cn/yIhvScYsoLs
  data = { path: "/pages/news_details/index", query: "id=193&spreader_uid=721", is_expire:false }
  ap gen_weapp_url_link data


  #端午促销信息
  https://wxaurl.cn/3vpKoA6qCJm
  data = { path: "/pages/news_details/index", query: "id=252&spreader_uid=736", is_expire:false }
  ap gen_weapp_url_link data

=end
def gen_weapp_url_link data
  wechat_post :generateWeappUrlLink, data
end

def get_wework_contact_points
  data = {}
  res = wechat_get :getWeworkContactPoints, data
  return res['follow_user']
end

def weworkCorpTagList
  if @weworkCorpTagList.nil?
      @weworkCorpTagList = get_wework_corp_tag_list
      return @weworkCorpTagList
  end
  return @weworkCorpTagList
end

def weworkCorpTagNameList
  if @weworkCorpTagNameList.nil?
      @weworkCorpTagNameList = get_wework_corp_tag_name_list
      return @weworkCorpTagNameList
  end
  return @weworkCorpTagNameList
end

#if trade state is success, we return time_end, otherwise return 0
def queryWechatTradePaytime trade_no = ''# 'wx168522386055598202'
    pay_time = 0
    uri = "https://mall.totembio.cn/api/query_wechat_pay_order?trade_no=#{trade_no}"
    begin
        res = RestClient.get uri
        body = JSON.parse res.body
        query = JSON.parse body['msg']
        if query['trade_state'] && query['time_end']
            if query['trade_state'] == 'SUCCESS'
                time_end = query['time_end']
                pay_time = Time.parse(time_end, "%Y%m%d%H%M%S%x").to_i
                #ap query
                return pay_time
            end
        end
    rescue=>e
    end
    return pay_time
end

def sendMarkdownToWeworkUsers touser='DongXueFeng', content="Hello\nWorld"
    notice = { touser: touser, msgtype: 'markdown', agentid: 2000003, markdown: { content: content } }
    res = wechat_post :sendWeworkNotice, notice
end

def convertWeworkOpenidToUserid openid
    data = {openid: openid}
    res = wechat_post :convertWeworkOpenidToUserid, data
    ap res
end
#sendMarkdownToWeworkUsers touser='DongXueFeng|Yanghai', content="Something wired - call 911"
